<?php

abstract class Page {

    protected static $instance = NULL;
    protected $title;
    protected $description;
    protected $keywords = array();
    protected $javascripts = array();
    protected $CSSStyles = array();
    protected $bodyAttributes = array();
    protected $menu;
    protected $content;
    protected $dumpForTest = '';
    protected $header;
    protected $footer;

    private function __construct() {
        return;
    }

    /**
     * @return Page
     *
     */
    public static function getInstance($application = __APPLICATION__) {
        if (self::$instance === NULL) {
            $page = PageBackend::getInstance();
            self::$instance = $page;
        }

        return self::$instance;
    }

    public function setTitle($title) {
        $this->title = $title;
    }

    public function setDescription($description) {
        $this->description = $description;
    }

    public function addKeyword($keyword) {
        $this->keywords[] = $keyword;
    }

    public function setKeywords($value) {
        if (is_array($value)) {
            $this->keywords = array_merge($this->keywords, $value);
        } else {
            $keywords = explode(',', $value);
            foreach ($keywords as $keyword) {
                $this->keywords[] = $keyword;
            }
        }
    }

    public function addScript($scriptFile, $scriptType = 'javascript') {
        if (in_array($scriptFile, $this->javascripts)) {
            return;
        }
        $this->javascripts[] = $this->resolveURL($scriptFile);
    }

    public function addStyle($styleFile, $styleType = 'css') {
        if (in_array($styleFile, $this->CSSStyles)) {
            return;
        }
        $this->CSSStyles[] = $styleFile;
    }

    private function resolveURL($url) {

        return $url;
        
    }

    public function setContent($content, $mode = 'w') { //mode w: for wrting from the beginning, p: for prepend, a: for append content

        if (Utility::isAjaxRequest()) {
            throw new Exception('This is ajax request please add the conent to reponse not web page');
        }

        switch ($mode) {
            case 'a' :
                $this->content = $content . $this->content;
                break;
            case 'p' :
                $this->content = $this->content . $content;
                break;
            case 'w' :
            default :
                $this->content = $content;
                break;
        }
    }

    public function appendContent($content) {
        $this->setContent($this->getContent(), 'a');
    }

    public function prependContent($content) {
        $this->setContent($content, 'p');
    }

    public function clearContent() {
        $this->content = '';
    }

    abstract public function getBody();

    private function buildDocument() {

        $xtpl = new XTemplate(Utility::getFileContent(DIR_TEMPLATES_WEBPAGE . DS. 'document.tpl.html'));


        foreach ($this->javascripts as $javascript) {
            $xtpl->assign('scriptFile', $javascript);
            $xtpl->parse('main.script');
        }
        foreach ($this->CSSStyles as $CSSStyle) {
            $xtpl->assign('styleFile', $CSSStyle);
            $xtpl->parse('main.style');
        }
        foreach ($this->bodyAttributes as $bodyAttributeKey => $bodyAttributeValue) {
            $xtpl->assign('bodyAttribute', $bodyAttributeKey . '="' . $bodyAttributeValue . '"');
            $xtpl->parse('main.bodyAttribute');
        }


        $xtpl->assign('title', $this->title);
        $xtpl->assign('description', str_replace('"', "'", $this->description));
        $xtpl->assign('keywords', str_replace('"', "'", implode(', ', $this->keywords)));
        $xtpl->assign('body', $this->getBody());
        $xtpl->assign('BASE_URL', BASE_URL);
        $xtpl->assign('dump', $this->getDump());



        $xtpl->parse('main');

        $document = $xtpl->out('main');
        return $document;
    }

    private function renderDocument($document) {

        return $document;
    }

    public function getDocument() {

        $document = $this->buildDocument();
        $document = $this->renderDocument($document);
        return $document;
    }

    public function addBodyAttribute($key, $value) {
        $this->bodyAttributes[$key] = $value;
    }

    private function getDump() {
        $dump = ob_get_contents();
        ob_clean();
        return $dump;
    }

}

?>